A type system defines program behavior by how expressions, values and the like are classified into types and the interaction between types. Types, or more specifically, data types, specify constraints on data utilization. A type system can be utilized to perform many useful tasks including type checking, among other things, to identify programmatic errors as a function of types associated with data. Thus, a degree of program safety can be obtained by detecting meaningless or likely invalid code.
Type systems vary across programming languages. For instance, programming languages can be statically or dynamically typed. A statically typed language (e.g., C, Java, Haskell . . . ) enables a program to be type checked at compile time prior to execution. Accordingly, all types are known at compile time, for example by explicit specification or type inference. Dynamically typed languages (e.g., JavaScript, Smalltalk . . . ) differ in that they are type checked at runtime. Consequently, types need not be explicitly specified prior to use, rather they are determined during execution.
There are various tradeoffs with respect to static and dynamic typing. In particular, static typing is beneficial in that errors can be detected prior to execution and programs can execute very efficiently. Further, design time experience can be improved since assistance such as automatic fills and suggestions can be provided based on types. However, dynamically typed languages allow more programmatic flexibility than static typed languages while still providing a degree of type safety by way of runtime checking. Furthermore, dynamically typed languages are easier to use, as programmers need not be concerned with type specification.